package ciyuan.Block.TypeInterface;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.HorizontalBlock;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.network.PacketBuffer;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.DirectionProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.*;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkHooks;

import java.util.function.ToIntFunction;

/**
 * @author 150149
 */
public abstract class Machine extends Block {

    public Machine() {
        super(Properties.of(Material.HEAVY_METAL)
                .sound(SoundType.ANVIL)
                .noOcclusion()
                .harvestLevel(2)
                .requiresCorrectToolForDrops()
                .strength(3.0F, 3.0F)
                .lightLevel(litBlockEmission(15))
        );
        this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.NORTH).setValue(LIT, false));
    }

    public static final DirectionProperty FACING = HorizontalBlock.FACING;
    public static final BooleanProperty LIT = BlockStateProperties.LIT;
    protected MachineTileEntity tileEntity;

    @Override
    public boolean hasTileEntity(BlockState Anvilate) {
        return true;
    }

    @Override
    public BlockState getStateForPlacement(BlockItemUseContext p_196258_1_) {
        return this.defaultBlockState().setValue(FACING, p_196258_1_.getHorizontalDirection().getOpposite());
    }

    @Override
    public ActionResultType use(BlockState Jymsqate, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) {
        if (!worldIn.isClientSide() && handIn == Hand.MAIN_HAND) {
            if (!tileEntity.hasLevel()) {
                tileEntity.setLevelAndPosition(worldIn, pos);
            }
            NetworkHooks.openGui((ServerPlayerEntity) player, tileEntity, (PacketBuffer packerBuffer) -> {
                packerBuffer.writeBlockPos(tileEntity.getBlockPos());
            });
        }
        return ActionResultType.SUCCESS;
    }

    @Override
    public BlockState rotate(BlockState p_185499_1_, Rotation p_185499_2_) {
        return p_185499_1_.setValue(FACING, p_185499_2_.rotate(p_185499_1_.getValue(FACING)));
    }

    @Override
    public BlockState mirror(BlockState p_185471_1_, Mirror p_185471_2_) {
        return p_185471_1_.rotate(p_185471_2_.getRotation(p_185471_1_.getValue(FACING)));
    }

    @Override
    protected void createBlockStateDefinition(StateContainer.Builder<Block, BlockState> p_206840_1_) {
        p_206840_1_.add(FACING, LIT);
    }

    @Override
    public boolean canEntityDestroy(BlockState state, IBlockReader world, BlockPos pos, Entity entity) {
        return hasItem();
    }

    public boolean hasItem() {
        return !tileEntity.getInventory().isEmpty();
    }

    private static ToIntFunction<BlockState> litBlockEmission(int i) {
        return (blockState) -> blockState.getValue(BlockStateProperties.LIT) ? i : 0;
    }

}
